linux_aria

My file bash, and configurate for linux


Project maintained by ariafatah0711 Hosted on GitHub Pages — Theme by mattgraham

1

pengenalan container

image

pengenalan kubernetes, openshift

Kubernetes dan Red Hat OpenShift Container Platform (RHOCP)

2

ansible (opsional)

podman

command

podman -v
podman pull registry.redhat.io/rhel7/rhel:7.9
podman images
podman run registry.redhat.io/rhel7/rhel:7.9 echo 'Red Hat' # run foregond
podman ps
podman ps -a
podman run --rm registry.redhat.io/rhel7/rhel:7.9 echo 'Red Hat' ## run and remove
podman ps --all --format=json
podman run -d # detecth (latar belakang)
podman run -p 8081:80 # port forwading
podman run -e NAME='Red Hat' # environment

podman-desktop

lab 1

podman run --rm registry.ocp4.example.com:8443/ubi8/ubi-minimal:8.5 \
 echo 'Hello Red Hat'
podman run --rm -e GREET=Hello -e NAME='Red Hat' \
 registry.ocp4.example.com:8443/ubi8/ubi-minimal:8.5 printenv GREET NAME
podman run --rm -p 8080:8080 \
 registry.ocp4.example.com:8443/ubi8/httpd-24

podman network

command

podman network create
podman network ls
podman network inspect
podman network rm
podman network prune
podman network connect # Menghubungkan kontainer yang sudah berjalan ke atau dari jaringan yang ada. Atau, sambungkan kontainer ke jaringan Podman

podman network create example-net
podman run -d --name my-container --net example-net container-image:latest
podman run -d --name double-connector --net postgres-net,redis-net\
 container-image:latest # multiple net
podman network connect example-net my-container

podman port -a
podman port <name_container>

lab 2

grep -i listen podman-info-times/app/main.go
cat podman-info-times/Containerfile
podman network inspect podman | jq .[].subnets
podman network inspect podman | jq .[].dns_enabled

podman network create cities
podman run --name times-app \
--network cities -p 8080:8080 -d \
registry.ocp4.example.com:8443/redhattraining/podman-info-times:v0.1

podman inspect times-app \
-f ''
podman inspect times-app | jq .[].NetworkSettings.Networks.cities

podman access

alt text

lab 3

podman run --name nginx -d -p 8080:8080 \
  registry.ocp4.example.com:8443/redhattraining/podman-nginx-helloworld
podman cp nginx:/var/log/nginx/error.log error.log
podman cp nginx:/etc/nginx/nginx.conf . # copy to host
podman cp nginx.conf nginx:/etc/nginx # copy to container
podman exec nginx nginx -s reload

lab 4

podman run --name httpd -d -p \
 8080:8080 registry.ocp4.example.com:8443/ubi8/httpd-24

podman ps
podman inspect --format='' httpd # running
podman inspect --format='' httpd # true

podman stop -l
podman inspect --format='' httpd # exited
podman inspect --format='' httpd # false

podman restart httpd # running

podman rm httpd
podman rm httpd --force # remove meskipun running status

podman run --name greeter -d \
registry.ocp4.example.com:8443/redhattraining/podman-greeter-ignore-sigterm

podman stop greeter --time=5
podman restart greeter
podman kill greeter # kill signal jadi restartnya tidak akan jadi

lab soal

alt text

lab start basics-podman
podman cp basics-podman-secret:/etc/secret-file solution ~/DO188/labs/basics-podman/solution

podman network create lab-net
podman run -d --name basics-podman-server \
--net lab-net -p 8080:8080 registry.ocp4.example.com:8443/ubi8/httpd-24

podman cp index.html basics-podman-server:/var/www/html/

podman run -d --name basics-podman-client \
--net lab-net registry.ocp4.example.com:8443/ubi8/httpd-24

podman network inspect lab-net
podman exec basics-podman-client \
curl -s http://basics-podman-server:8080 && echo

3

registery

# registry.redhat.io/ubi8/ubi:8.6
# registery / namespace / image : tag
# registry.access.redhat.com: requires no authentication
# registry.redhat.io: requires authentication

vi /etc/containers/registries.conf 

# list
unqualified-search-registries == ['registry.redhat.io', 'docker.io']

# block
[[registry]]
location="docker.io"
blocked=true

skopoe

skopeo inspect \
 docker://registry.access.redhat.com/ubi9/nodejs-18

skopeo copy \
 docker://registry.access.redhat.com/ubi9/nodejs-18 \
 dir:/var/lib/images/nodejs-18

podman login

cat ${XDG_RUNTIME_DIR}/containers/auth.json

lab 1

lab start images-basics
oc login -u admin -p redhatocp \
    https://api.ocp4.example.com:6443
podman login -u $(oc whoami) -p $(oc whoami -t) \
  default-route-openshift-image-registry.apps.ocp4.example.com
podman login -u developer -p developer \
  registry.ocp4.example.com:8443

RHOCP_REGISTRY="default-route-openshift-image-registry.apps.ocp4.example.com"
skopeo copy --dest-tls-verify=false \
  docker://${RHOCP_REGISTRY}/default/python:3.9-ubi8 \
  docker://registry.ocp4.example.com:8443/developer/python:3.9-ubi8

## In a web browser, navigate to https://registry.ocp4.example.com:8443 and log in with the user developer and password developer.
## Type developer in the Filter Repositories field, then click the developer/python repository.
## Click the Settings icon at the bottom of the page. Scroll to the Repository Visibility settings and click Make Public. Then, click OK.

podman logout --all  
podman pull \
  registry.ocp4.example.com:8443/developer/python:3.9-ubi8

podman run --rm \
  registry.ocp4.example.com:8443/developer/python:3.9-ubi8 python3 --version

manage images

# [<image repository>/<namespace>/]<image name>[:<tag>]
podman image tag LOCAL_IMAGE:TAG LOCAL_IMAGE:NEW_TAG
podman search nginx

podman build --file Containerfile \
  --tag quay.io/YOUR_QUAY_USER/IMAGE_NAME:TAG

podman push quay.io/YOUR_QUAY_USER/IMAGE_NAME:TAG

podman image rm -f REGISTRY/NAMESPACE/IMAGE_NAME:TAG
podman rmi --all
podman image rm --all

podman image prune
podman image prune -a
podman image prune -af

podman export -o mytarfile.tar fb601b05cd3b
podman import mytarfle.tar httpdcustom:2.4

lab 2

lab start images-managing

podman image ls --format ""
cd ~/DO188/labs/images-managing

podman build -f Containerfile -t \
simple-server

podman image ls
podman run -d \
  -p 8080:8000 \
  --name http-server \
  simple-server

curl http://localhost:8080/hello.html
podman image inspect simple-server \
  --format=""

podman image tag simple-server \
simple-server:0.1

podman image ls
podman image rm simple-server
podman image rm simple-server:0.1
podman image rm -f simple-server:0.1

lab soal

alt text

lab start images-lab
podman login -u developer -p developer registry.ocp4.example.com:8443
cd ~/DO188/labs/images-lab
podman build --file Containerfile --tag registry.ocp4.example.com:8443/developer/images-lab
podman push registry.ocp4.example.com:8443/developer/images-lab

podman tag registry.ocp4.example.com:8443/developer/images-lab registry.ocp4.example.com:8443/developer/images-lab:grue
podman push registry.ocp4.example.com:8443/developer/images-lab:grue

podman run -d --name images-lab -p 8080:8080 images-lab:grue
curl localhost:8080
lab finish images-lab

4

Containerfile

# This is a comment line 1
FROM        registry.redhat.io/ubi8/ubi:8.6 2
LABEL       description="This is a custom httpd container image" 3
RUN         yum install -y httpd 4
EXPOSE      80 5
ENV         LogLevel "info" 6
ADD         http://someserver.com/filename.pdf /var/www/html 7
COPY        ./src/   /var/www/html/ 8
USER        apache 9
ENTRYPOINT  ["/usr/sbin/httpd"] 10
CMD         ["-D", "FOREGROUND"] 

man Containerfile

lab 1

lab start custom-containerfiles
cat > Containerfile << EOF
FROM registry.ocp4.example.com:8443/redhattraining/podman-ubi9.2

COPY . /tmp/hello-server
RUN dnf module enable -y nodejs:18
RUN dnf install -y nodejs
RUN cd /tmp/hello-server && npm install

CMD cd /tmp/hello-server && npm start
EOF

podman build -t hello-server:bad .
podman run -d --rm --name hello-bad -p 3000:3000 hello-server:bad
curl http://localhost:3000/greet ;echo
podman image tree hello-server:bad

cat > Containerfile << EOF
FROM registry.ocp4.example.com:8443/redhattraining/podman-ubi9.2

WORKDIR /tmp/hello-server
COPY ..
RUN dnf module enable -y nodejs:18 && \
    dnf install -y nodejs && \
    npm install 

CMD npm start
EOF

podman build -t hello-server:better .
podman image tree hello-server:better
podman run -d --rm --name hello-better -p 3000:3000 hello-server:better
curl http://localhost:3000/greet ;echo
podman stop hello-better

cat > Containerfile << EOF
FROM registry.ocp4.example.com:8443/ubi9/nodejs-18:1

LABEL org.opencontainers.image.authors="aria"
LABEL com.example.environment="production"
LABEL com.example.version="0.0.1"

ENV SERVER_PORT=3000
ENV NODE_ENV="production"

EXPOSE $SERVER_PORT

WORKDIR /opt/app-root/src
COPY . .
RUN npm install

CMD npm start
EOF

podman build -t hello-server:best .
podman inspect hello-server:best -f ''
podman run -d --rm --name hello-best -p 3000:3000 hello-server:best

curl http://localhost:3000/greet ;echo
podman stop hello-best

advance container file

# ENV
ENV DB_HOST="database.example.com"

##
from os import environ
DB_HOST = environ.get('DB_HOST')
# Connect to the database at DB_HOST...
##

## ARG
ARG key[=default value]

ARG VERSION="1.16.8" \
    BIN_DIR=/usr/local/bin/
ENV VERSION=${VERSION} \
    BIN_DIR=${BIN_DIR}
RUN curl "https://dl.example.io/${VERSION}/example-linux-amd64" \
        -o ${BIN_DIR}/example

ARG VERSION \
    BIN_DIR
ENV VERSION=${VERSION:-1.16.8} \
    BIN_DIR=${BIN_DIR:-/usr/local/bin/}
RUN curl "https://dl.example.io/${VERSION}/example-linux-amd64" \
        -o ${BIN_DIR}/example

## volume
FROM registry.redhat.io/rhel9/postgresql-13:1
VOLUME /var/lib/pgsql/data

podman volume prune
podman volume create VOLUME_NAME
podman volume ls --format="\t"

## ENTRYPOINT
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.5
ENTRYPOINT ["echo", "Hello"]

podman run my-image # Hello
podman run my-image Red Hat # Hello Red Hat

## CMD
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.5
CMD ["echo", "Hello", "Red Hat"]

podman run my-image # Hello Red Hat
podman run my-image whoami # root

## BOTH (ENTRYPOINT AND CMD)
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.5
ENTRYPOINT ["echo", "Hello"]
CMD ["Red", "Hat"]

podman run my-image # Hello Red Hat
podman run my-image Podman # Hello Podman

## Text Array
ENTRYPOINT ["executable", "param1", ... "paramN"]

# string form
CMD executable param1 ... paramN 

FROM registry.access.redhat.com/ubi8/ubi-minimal:8.5
LABEL GREETING="World"
ENTRYPOINT echo Hello "${GREETING}"

podman run my-image # Hello
podman run my-image env # Hello
podman run --entrypoint env my-image
# show env

## Podman Secrets
echo "R3d4ht123" > dbsecretfile
podman secret create dbsecret dbsecretfile
printf "R3d4ht123" | podman secret create dbsecret2 - # 875a1e46fa64639756968c644

podman secret ls
podman secret rm dbsecret2
podman run -it --secret dbsecret --name myapp registry.access.redhat.com/ubi8/ubi /bin/bash

cat /run/secrets/dbsecret

## multistage build
# First stage
FROM registry.access.redhat.com/ubi8/nodejs-14:1 as builder 1
COPY ./ /opt/app-root/src/
RUN npm install
RUN npm run build 2

# Second stage
FROM registry.access.redhat.com/ubi8/nginx-120 3
COPY --from=builder /opt/app-root/src/ /usr/share/nginx/html 

podman build -t localhost/not-squashed .
podman build --squash -t localhost/squashed .
podman build --squash-all -t localhost/squashed-all .

podman images --format="\t"
[localhost/not-squashed:latest]  419 MB 1
[localhost/squashed:latest]      419 MB 2
[localhost/squashed-all:latest]  394 MB 3

lab 2

lab start custom-advanced

cd ~/DO188/labs/custom-advanced
cat > Containerfile << EOF
FROM registry.ocp4.example.com:8443/redhattraining/podman-random-numbers as generator
RUN python3 random_generator.py

FROM registry.ocp4.example.com:8443/ubi8/python-38:1-96

ENV FILE="/redhat/materials/numbers.txt"
USER default
WORKDIR /redhat

COPY --from=generator --chown=default /app/numbers.txt materials/numbers.txt
COPY main.py .

VOLUME /redhat/materials

CMD python3 main.py
EOF

podman build -t redhat-local/custom-advanced .
podman run --rm --name=custom-advanced redhat-local/custom-advanced
# Current content: ['17 72 97 8 32 15 63 97 57']

rootles podman

# change contaienr user
## default
podman run registry.access.redhat.com/ubi9/ubi id

FROM registry.access.redhat.com/ubi9/ubi
CMD ["python3", "-m", "http.server"]

FROM registry.access.redhat.com/ubi9/ubi

## mengubah user (keamanan)
RUN adduser \
   --no-create-home \
   --system \
   --shell /usr/sbin/nologin \
   python-server

USER python-server

CMD ["python3", "-m", "http.server"]

## pemetaan user
cat /etc/subuid /etc/subgid
# student:100000:65536
# student:100000:65536

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 student
grep student /etc/subuid /etc/subgid
# /etc/subuid:student:100000:65536
# /etc/subgid:student:100000:65536

podman run -it registry.access.redhat.com/ubi9/ubi bash
podman top e6116477c5c9 huser user
# HUSER       USER
# 1000        root

cat /proc/self/uid_map /proc/self/gid_map

## no rootles
sudo sysctl -w "net.ipv4.ip_unprivileged_port_start=79"
sudo sysctl -w "net.ipv4.ping_group_range=0 2000000"

lab 3

lab start custom-rootless

cd $HOME/DO188/labs/custom-rootless/gitea
podman build -t gitea .

sudo !! # previous command with sudo
sudo $HOME/DO188/labs/custom-rootless/ids.sh # menghapus mapping id pengguna

podman run --rm -p 3030:3030 gitea # error
sudo podman run --name root-gitea -p 3030:3030 --rm gitea # work
sudo podman exec root-gitea cat /proc/self/uid_map /proc/self/gid_map # root (not secure)
# 0          0 4294967295
# 0          0 4294967295

sudo podman stop root-gitea
sudo touch /etc/{subuid,subgid}

sudo usermod --add-subuids 100000-165536 --add-subgids 100000-165536 student
cat /etc/subuid /etc/subgid

podman run --rm -p 3030:3030 --name gitea gitea # error
podman system migrate # migrasi rentang id pengguna

podman run --name gitea --rm -p 3030:3030 gitea # work
podman stop gitea

sudo $HOME/DO188/labs/custom-rootless/ids.sh
lab finish custom-rootless

lab soal

alt text

lab start custom-lab

cd ~/DO188/labs/custom-lab
npm install; npm start

# add  "RUN ./gen_certificates.sh" in first stage build

# dibagian bawah tambahnakn ENV, WORKDIR, USER, RUN, ENTRYPOINT

# add ENV
## ENV TLS_PORT=8443 \
##  HTTP_PORT=8080
##  CERTS_PATH="/etc/pki/tls/private/certs"
# add WORKDIR /app in Containerfile
# add USER student in Containerfile
# add "RUN npm install --omit=dev"
# add ENTRYPOINT npm start

podman build . -t localhost/podman-qr-app
podman run --name custom-lab -p 8080:8080 -p 8443:8443 localhost/podman-qr-app

5

Persisting Data

FROM registry.access.redhat.com/ubi8/ubi-minimal

RUN microdnf install httpd
RUN microdnf clean all
RUN rm -rf /var/cache/yum

CMD httpd -DFOREGROUND

## commnad
--volume /path/on/host:/path/in/container:OPTIONS
--mount type=TYPE,source=/path/on/host,destination=/path/in/container

## example
podman run -p 8080:8080 --volume  /www:/var/www/html:ro \
  registry.access.redhat.com/ubi8/httpd-24:latest

# selinux
podman run -p 8080:8080 --volume /www:/var/www/html \
  registry.access.redhat.com/ubi8/httpd-24:latest

podman unshare ls -l /www/
# -rw-rw-r--. 1 root root 21 Jul 12 15:21 index.html
podman unshare ls -ld /www/
# drwxrwxr-x. 1 root root 20 Jul 12 15:21 /www/
ls -Zd /www
# system_u:object_r:default_t:s0:c228,c359 /www
# The output shows the SELinux context label system_u:object_r:default_t:s0:c228,c359, which has the default_t type. A container must have the container_file_t SELinux type to have access to the bind mount. SELinux is out of scope for this course.
ls -Zd /www
# system_u:object_r:container_file_t:s0:c240,c717 /www

## storing data with volume
podman volume create http-data
podman volume inspect http-data
podman run -p 8080:8080 --volume  http-data:/var/www/html \
  registry.access.redhat.com/ubi8/httpd-24:latest
podman volume import http_data web_data.tar.gz
podman volume export http_data --output web_data.tar.gz

## storing data with a tmpsfs mount
podman run -e POSTGRESQL_ADMIN_PASSWORD=redhat --network lab-net \
  --mount  type=tmpfs,tmpfs-size=512M,destination=/var/lib/pgsql/data \
  registry.redhat.io/rhel9/postgresql-13:1

lab 1

lab start persisting-mounting

cat ~/DO188/labs/persisting-mounting/podman-python-server/Containerfile
cp ~/DO188/labs/persisting-mounting/index.html ~/www
podman run -ti --rm --name podman-server \
  --volume ~/www:/server:Z -p 8000:8000 \
  registry.ocp4.example.com:8443/redhattraining/podman-python-server
# open localhost:8000 (error)
# logs: 10.0.2.100 - - [28/Jun/2022 13:21:08] code 404, message No permission to list directory

podman unshare ls -l --directory ~/www
# drwxrwx---. 1 root root 20 Jun 28 14:56 /home/student/www
podman run --rm registry.ocp4.example.com:8443/redhattraining/podman-python-server id
# uid=994(python-server) gid=994(python-server) groups=994(python-server)
podman unshare chgrp -R 994 ~/www
podman unshare ls -ln --directory ~/www
# drwxrwx---. 1 0 994 20 Jun 28 14:56 /home/student/www
# open localhost:8000 (success)

podman volume create html-vol
cd ~/DO188/labs/persisting-mounting
podman volume import html-vol index.tar.gz
podman run -ti --rm --name podman-server -p 8000:8000 \
   --mount 'type=volume,source=html-vol,destination=/server,ro' \
   registry.ocp4.example.com:8443/redhattraining/podman-python-server
# open localhost:8000

Working with Databases

# import database data
podman cp SQL_FILE TARGET_DB_CONTAINER:CONTAINER_PATH
podman exec -it DATABASE_CONTAINER \
  psql -U DATABASE_USER -d DATABASE_NAME \
       -f CONTAINER_PATH/SQL_FILE
podman run -it --rm \
  -e PGPASSWORD=DATABASE_PASSWORD \
  -v ./SQL_FILE:/tmp/SQL_FILE:Z \
  --network DATABASE_NETWORK \
  registry.redhat.io/rhel8/postgresql-12:1-113 \
  psql -U DATABASE_USER -h DATABASE_CONTAINER \
       -d DATABASE_NAME -f /tmp/SQL_FILE
# export database data
podman exec POSTGRESQL_CONTAINER \
  pg_dump -Fc DATABASE -f BACKUP_DUMP

lab 2

lab start persisting-databases
podman run -it --rm \
  --name persisting-pg12 \
  -e POSTGRESQL_USER=backend \
  -e POSTGRESQL_PASSWORD=secret_pass \
  -e POSTGRESQL_DATABASE=rpi-store \
  -v ~/DO188/labs/persisting-databases:/opt/app-root/src/postgresql-start:Z \
  registry.ocp4.example.com:8443/rhel8/postgresql-12:1-113
podman exec -it persisting-pg12 \
  psql -d rpi-store -c "select * from model"

## 2
podman run -it --rm \
  --name persisting-pg12 \
  -e POSTGRESQL_USER=backend \
  -e POSTGRESQL_PASSWORD=secret_pass \
  -e POSTGRESQL_DATABASE=rpi-store \
  registry.ocp4.example.com:8443/rhel8/postgresql-12:1-113
podman exec -it persisting-pg12 \
  psql -d rpi-store -c "select * from model"

## 3
podman volume create rpi-store-data
podman run -d \
  --name persisting-pg12 \
  -e POSTGRESQL_USER=backend \
  -e POSTGRESQL_PASSWORD=secret_pass \
  -e POSTGRESQL_DATABASE=rpi-store \
  -v rpi-store-data:/var/lib/pgsql/data \
  -v ~/DO188/labs/persisting-databases:/opt/app-root/src/postgresql-start:Z \
  registry.ocp4.example.com:8443/rhel8/postgresql-12:1-113
podman exec -it persisting-pg12 \
  psql -d rpi-store -c "select * from model"

## 4
podman rm -f persisting-pg12
podman run -d \
  --name persisting-pg12 \
  -e POSTGRESQL_USER=backend \
  -e POSTGRESQL_PASSWORD=secret_pass \
  -e POSTGRESQL_DATABASE=rpi-store \
  -v rpi-store-data:/var/lib/pgsql/data \
  registry.ocp4.example.com:8443/rhel8/postgresql-12:1-113
podman exec -it persisting-pg12 \
  psql -d rpi-store -c "select * from model"

## 5
podman network create persisting-network
podman rm -f persisting-pg12
podman run -d \
  --name persisting-pg12 \
  -e POSTGRESQL_USER=backend \
  -e POSTGRESQL_PASSWORD=secret_pass \
  -e POSTGRESQL_DATABASE=rpi-store \
  -v rpi-store-data:/var/lib/pgsql/data \
  --network persisting-network \
  registry.ocp4.example.com:8443/rhel8/postgresql-12:1-113
podman run -d \
  --name persisting-pgadmin \
  -e PGADMIN_SETUP_EMAIL=gls@example.com \
  -e PGADMIN_SETUP_PASSWORD=pga_secret_pass \
  -p 5050:5050 \
  --network persisting-network \
  registry.ocp4.example.com:8443/crunchydata/crunchy-pgadmin4:ubi8-4.30-1

## login in localhost:5050 with cred gls@example.com:pga_secret_pass
## Connect to the persisting-pg12 database container by clicking Add New Server.
## In the General tab, set rpi-store as the name.
## Switch to the Connection tab. Fill the form with the following data and leave the rest of the fields with their default values.
# Hostname/address	persisting-pg12
# Username	backend
# Password	secret_pass
## View the data in the model table to verify the pgAdmin access to the rpi-store database in the persisting-pg12 container. 
## Select the model table by clicking Servers > rpi-store > Databases > rpi-store > Schemas > public > Tables > model.
## Click the View Data icon to verify that pgAdmin queries the data in the persisting-pg12 container.

# 6
podman exec persisting-pg12 \
  pg_dump -Fc rpi-store -f /tmp/db_dump
podman cp persisting-pg12:/tmp/db_dump /tmp/db_dump
podman stop persisting-pg12
podman volume create rpi-store-data-pg13
podman run -d \
  --name persisting-pg13 \
  -e POSTGRESQL_USER=backend \
  -e POSTGRESQL_PASSWORD=secret_pass \
  -e POSTGRESQL_DATABASE=rpi-store \
  -v rpi-store-data-pg13:/var/lib/pgsql/data \
  registry.ocp4.example.com:8443/rhel9/postgresql-13:1
podman cp /tmp/db_dump persisting-pg13:/tmp/db_dump
podman exec persisting-pg13 \
  pg_restore -d rpi-store /tmp/db_dump
podman exec -it persisting-pg13 \
  psql -d rpi-store -c "select * from model"
podman rm persisting-pg12
podman volume rm rpi-store-data

lab soal

alt text

lab start persisting-lab

podman volume create postgres-vol
podman volume import postgres-vol ~/DO188/labs/persisting-lab/postgres-vol.tar.gz

podman network create persisting-net
podman run --name persisting-db -d \
 --net persisting-net -e POSTGRESQL_USER=user \
 -e POSTGRESQL_PASSWORD=pass -e POSTGRESQL_DATABASE=db \
 --mount='type=volume,src=postgres-vol,dst=/var/lib/pgsql/data' \
 registry.ocp4.example.com:8443/rhel9/postgresql-13:1

podman run --name persisting-backend -d \
 -e DB_HOST=persisting-db -p 8080:8080 --net persisting-net \
 registry.ocp4.example.com:8443/redhattraining/podman-urlshortener-backend

podman run --name persisting-frontend -d \
  --net persisting-net -p 3000:8080 \
  registry.ocp4.example.com:8443/redhattraining/podman-urlshortener-frontend

6

container loging and trobleshooting

podman ps -a
podman logs CONTAINER
podman port CONTAINER
podman exec -it CONTAINER ss -pant
podman inspect CONTAINER --format ''
sudo nsenter -n -t CONTAINER_PID ss -pant
podman inspect CONTAINER --format=''
# map[network_name:0xc000a825a0]
podman network inspect NETWORK

## podman event
podman info --format 
# journald
podman events --stream=false
podman events --filter event=create --filter type=container --stream=false
podman events --since 5m --stream=false

lab 1

lab start troubleshooting-logging
podman logs smart-home-api
podman inspect \
  smart-home-db --format=''
podman network inspect troubleshooting-lab
podman inspect \
  smart-home-api --format=''
podman rm smart-home-api

podman run -d --rm \
  --name smart-home-api \
  -e DB_HOST=smart-home-db -e DB_USER=backend -e DB_PASSWORD=secret_pass \
  -p 8080:8080 \
  --network troubleshooting-lab \
  registry.ocp4.example.com:8443/redhattraining/smart-home-api:1.0
podman logs smart-home-api

podman exec \
  smart-home-api curl http://localhost:8080/device/1

# curl: (7) Failed to connect to localhost port 8080: Connection refused
podman exec smart-home-api ss -pant
# Error: crun: executable file ss not found in $PATH: No such file or directory: OCI runtime attempted to invoke a command that was not found

podman inspect smart-home-api --format ''
sudo nsenter -t 2809 -n ss -pant
# tcp   LISTEN 0      2048       0.0.0.0:8000       0.0.0.0:*  users: "uvicorn",pid=76641,fd=23

podman exec -it \
  smart-home-api curl  http://localhost:8000/device/1
curl http://localhost:8080/device/1
podman stop smart-home-api
podman run -d --rm \
  --name smart-home-api \
  -e DB_HOST=smart-home-db -e DB_USER=backend -e DB_PASSWORD=secret_pass \
  -p 8080:8000 \
  --network troubleshooting-lab \
  registry.ocp4.example.com:8443/redhattraining/smart-home-api:1.0
curl http://localhost:8080/device/1
# {"id":1,"name":"Bedroom Light","state":"on"}%

cd ~/DO188/labs/troubleshooting-logging/smart-home
podman stop smart-home-api

podman run -d --rm \
  --name smart-home-api \
  -e DB_HOST=smart-home-db -e DB_USER=backend -e DB_PASSWORD=secret_pass \
  -p 8080:8000 \
  --network troubleshooting-lab \
  -v ./automations.yaml:/config/automations.yaml \
  registry.ocp4.example.com:8443/redhattraining/smart-home-api:1.0
curl http://localhost:8080/automations
podman exec \
  smart-home-api ls -l /config/
ls -Z automations.yaml
# system_u:object_r:user_home_t:s0 automations.yaml
podman stop smart-home-api

podman run -d --rm \
  --name smart-home-api \
  -e DB_HOST=smart-home-db -e DB_USER=backend -e DB_PASSWORD=secret_pass \
  -p 8080:8000 \
  --network troubleshooting-lab \
  -v ./automations.yaml:/config/automations.yaml:Z \
  registry.ocp4.example.com:8443/redhattraining/smart-home-api:1.0

ls -Z automations.yaml
# system_u:object_r:container_file_t:s0:c539,c793 automations.yaml
curl http://localhost:8080/automations
# [{"automation":"Turn garage lights ON when presence detected","wait_for_trigger":[{"platform":"event","event_type":"PRESENCE_DETECTED"},{"platform":"state","device_id":1,"to":"on","for":60}]}]

lab 2

lab start troubleshooting-debugging
cd ~/DO188/labs/troubleshooting-debugging/nodebug
cat package.json

podman build -t nodebug .
podman run -d --rm \
  --name nodebug -p 8080:8080 -p 9229:9229 \
  nodebug npm run debug
podman logs nodebug

codium .
# Yes, I trust the authors.
# Click Run → Add configuration to open a selection menu, and then click Node.js.
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "attach",
            "name": "Debug Nodebug",
            "port": 9229,
            "address": "localhost",
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/"
        }
    ]
}

# run start debug
curl localhost:8080/echo?message=hello
curl localhost:8080/snacks?search=apple
# sorry, we don't have any apples :(

app.get("/snacks", (req, res) => {
  const search == req.query.search;
  const available_snacks == ["apple", "cheese", "cracker", "lunchmeat", "olive"];
  for (const snack of available_snacks) {
    if (snack ==== search) {
      res.send(`yes, we have ${search}s!\n`);
      return;
    }
  }
  res.send(`sorry, we don't have any ${search}s :(\n`);
});
'

curl localhost:8080/snacks?search=apple
podman stop nodebug
npm install
podman run -d --rm \
  --name nodebug -p 8080:8080 -p 9229:9229 \
  -v .:/opt/app-root/src:Z \
  nodebug npm run debug
podman rm -f nodebug
rm -r node_modules
podman build -t nodebug .
podman run -d --rm \
  --name nodebug -p 8080:8080 nodebug
curl localhost:8080/snacks?search=apple
# yes, we have apples!

lab soal

alt text

lab start troubleshooting-lab

podman ps -a
podman logs quotes-ui
# nginx: [emerg] host not found in upstream "quotes-api-v1" in /etc/nginx/nginx.conf:45
podman inspect quotes-api-v1 --format=''
# map[troubleshooting-lab:0xc000a825a0]
podman inspect quotes-ui --format='' # map[]

podman rm quotes-ui
podman run -d \
  --name quotes-ui -p 3000:8080 \
  -e QUOTES_API_VERSION=v2 \
  --net troubleshooting-lab \
  registry.ocp4.example.com:8443/redhattraining/quotes-ui-versioning:1.0
podman ps

podman exec quotes-ui curl -s http://localhost:8080/api/v1/quotes # v1 work
podman exec quotes-ui curl -s http://localhost:8080/api/v2/quotes # v2 bad gateway

podman logs quotes-api-v2
# port:                         8081

podman exec quotes-ui cat /etc/nginx/nginx.conf
#  proxy_pass http://quotes-api-v2:8080;

cat ~/DO188/labs/troubleshooting-lab/nginx.conf
podman rm -f quotes-ui
podman run -d \
  --name quotes-ui \
  -p 3000:8080 \
  -e QUOTES_API_VERSION=v2 \
  --net troubleshooting-lab \
  -v ~/DO188/labs/troubleshooting-lab/nginx.conf:/etc/nginx/nginx.conf:Z \
  registry.ocp4.example.com:8443/redhattraining/quotes-ui-versioning:1.0

7

Multi-container (Compose)

# yaml
services:
  orders: 1
    image: quay.io/user/python-app 2
    ports:
    - 3030:8080 3
    environment:
      ACCOUNTS_SERVICE: http://accounts 4

# 1 Declare the orders container.
# 2 Use the python-app container image.
# 3 Bind the 3030 port on your host machine to the 8080 port within the container.
# 4 Pass the ACCOUNTS_SERVICE environment variable to the application.

# Podman Pods
# Podman introduced an alternative to orchestrate containers on a single host with the usage of Podman pods.

version (deprecated): Specifies the Compose version used.
services: Defines the containers used.
networks: Defines the networks used by the containers.
volumes: Specifies the volumes used by the containers.
configs: Specifies the configurations used by the containers.
secrets: Defines the secrets used by the containers.

# podman-compose
podman-compose up
podman network ls
podman-compose down

# network
services:
  frontend:
    image: quay.io/example/frontend
    networks: 1
      - app-net
    ports:
      - "8082:8080"
  backend:
    image: quay.io/example/backend
    networks: 2
      - app-net
      - db-net
  db:
    image: registry.redhat.io/rhel8/postgresql-13
    environment:
      POSTGRESQL_ADMIN_PASSWORD: redhat
    networks: 3
      - db-net

networks: 4
  app-net: {}
  db-net: {}

# volume
services:
  db:
    image: registry.redhat.io/rhel8/postgresql-13
    environment:
      POSTGRESQL_ADMIN_PASSWORD: redhat
    ports:
      - "5432:5432"
    volumes: 1
      - db-vol:/var/lib/postgresql/data

volumes: 2
  db-vol: {}

# services
services:
  db:
    image: registry.redhat.io/rhel8/postgresql-13
    environment:
      POSTGRESQL_ADMIN_PASSWORD: redhat
    ports:
      - "5432:5432"
    volumes:
      - my-volume:/var/lib/postgresql/data

volumes:
  my-volume:
    external: true

services:
  db:
    image: registry.redhat.io/rhel8/postgresql-13
    environment:
      POSTGRESQL_ADMIN_PASSWORD: redhat
    ports:
      - "5432:5432"
    volumes:
      - ./local/redhat:/var/lib/postgresql/data:Z

podman compose

podman --version
pip3 install podman-compose
pip3 install https://github.com/containers/podman-compose/archive/devel.tar.gz

# bash autocompleate command podman-compose

lab 1

lab start compose-environments
cd ~/DO188/labs/compose-environments
gedit compose.yml

# 
services:
  db-admin:
    image: "registry.ocp4.example.com:8443/crunchydata/crunchy-pgadmin4:ubi8-4.30-1"
    container_name: "compose_environments_pgadmin"
    environment:
      PGADMIN_SETUP_EMAIL: user@example.com
      PGADMIN_SETUP_PASSWORD: redhat
    ports:
      - "5050:5050"
  db:
    image: "registry.ocp4.example.com:8443/rhel9/postgresql-13:1"
    container_name: "compose_environments_postgresql"
    environment:
      POSTGRESQL_USER: backend
      POSTGRESQL_DATABASE: rpi-store
      POSTGRESQL_PASSWORD: redhat
    ports:
      - "5432:5432"
    volumes:
      - ./database_scripts:/opt/app-root/src/postgresql-start:Z
      - rpi:/var/lib/pgsql/data

volumes:
  rpi: {}
#

podman-compose up -d
podman-compose ps
podman volume list
podman-compose logs -n -f

## go http://localhost:5050. 
## Click Add New Server to connect to the compose_environments_postgresql database container.
## In the General tab, set rpi-store as the name.
## Switch to the Connection tab. Complete the form with the following data and leave the rest of the fields with their default values.
# Host name/address	db
# Username	backend
# Password	redhat
## Navigate to Servers → rpi-store → Databases → rpi-store, and then select Tools → Query Tool from the menu. In the Query Editor, enter the following query.
# select * from inventory
## Press F5 to execute the query and retrieve data from the inventory table.
## Modify the data in the inventory table. Double-click the 20 value in the quantity column. Enter 10 as the value, press Enter, and then press F6 to save the changes.

podman-compose down

lab soal

alt text

lab start compose-lab

cd ~/DO188/labs/compose-lab

cat > compose.yaml << EOF
services:
  wiremock:
    container_name: "quotes-provider"
    image: "registry.ocp4.example.com:8443/redhattraining/wiremock"
    volumes:
      - ~/DO188/labs/compose-lab/wiremock/stubs:/home/wiremock:Z
    networks:
      - lab-net
  quotes-api:
    container_name: "quotes-api"
    image: "registry.ocp4.example.com:8443/redhattraining/podman-quotesapi-compose"
    ports:
      - "8080:8080"
    networks:
      - lab-net
    environment:
      QUOTES_SERVICE: "http://quotes-provider:8080"
  quotes-ui:
    container_name: "quotes-ui"
    image: "registry.ocp4.example.com:8443/redhattraining/podman-quotes-ui"
    ports:
      - "3000:8080"

networks:
  lab-net: {}
EOF

podman-compose up -d

8

Kubernetes dan openshift

oc login https://api.ocp4.example.com:6443
Username: developer
Password: developer

oc get pod
# quotes-api-6c9f758574-nk8kd   1/1     Running   0          39m
# quotes-ui-d7d457674-rbkl7     1/1     Running   0          67s

oc create -f pod.yaml
oc delete pod quotes-ui
oc logs react-ui

# pod
cat > pod.yaml << EOF
kind: Pod 1
apiVersion: v1 2
metadata: 3
  name: example-pod
  namespace: example-namespace
spec: 4
...definition omitted...
status: 5
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-08-19T12:59:22Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: cri-o://e37c....f5c2
    image: quay.io/example/awesome-container:latest
    lastState: {}
    name: podman-quotes-ui
    ready: true
...object omitted...
EOF

oc explain pod.metadata.name
oc get pod --selector group=developers # label

## create pod with imperatif
oc run example-pod \
  --image=quay.io/example/awesome-container \
  --env GREETING='Hello from the awesome container' \
  --port=8080

## create pod with imperatif and with output yaml
oc run example-pod \
  --image=quay.io/example/awesome-container \
  --env GREETING='Hello from the awesome container' \
  --port=8080 \
  --dry-run=client -o yaml

# service
cat > service.yaml << EOF
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  ports:
  - port: 8080 1
    protocol: TCP
    targetPort: 8080 2
  selector: 3
    app: backend-app
EOF

oc expose pod backend-app \
  --port=8080 \ 1
  --targetPort=8080 \ 2
  --name=backend-app 3

man units

lab 1

lab start openshift-applications

oc login -u developer -p developer https://api.ocp4.example.com:6443
oc project ocp-applications

gedit ~/DO188/labs/openshift-applications/podman-hello-client/Containerfil
gedit ~/DO188/labs/openshift-applications/podman-hello-client/client.sh

# open page https://console-openshift-console.apps.ocp4.example.com
## login with cred developer:developer

oc whoami --show-context
# ocp-applications/api-ocp4-example-com:6443/developer
oc logs hello-client | tail -n 1

oc delete pod hello-client
oc run hello-client --env PORT=8080 \
  --image registry.ocp4.example.com:8443/redhattraining/podman-hello-client:latest

oc get pod
# NAME           READY   STATUS    RESTARTS   AGE
# hello-client   1/1     Running   0          32s
# hello-server   1/1     Running   0          83m

oc logs hello-client | tail -n 1
# {"hello":"world"}

lab finish openshift-applications

Multi-pod Applications

# deployments
cat > deploy.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata: 1
  labels:
    app: deployment-label
  name: example-deployment
spec:
  replicas: 3 2
  selector: 3
    matchLabels:
      app: example-deployment
  strategy: RollingUpdate 4
  template: 5
    metadata:
      labels:
        app: example-deployment
    spec: 6
      containers:
      - image: quay.io/example/awesome-container
        name: awesome-pod
EOF

oc create deployment example-deployment \
  --image=quay.io/example/awesome-container \
  --replicas=3 \
  --dry-run=client -o yaml

# routes
cat > routes.yaml << EOF
apiVersion: route.openshift.io/v1
kind: Route
metadata:
  labels:
    app: app-ui
  name: app-ui
  namespace: awesome-app
spec:
  port:
    targetPort: 8080 1
  host: ""
  to: 2
    kind: "Service"
    name: "app-ui"
EOF

oc expose service app-ui
oc expose service app-ui \
  --dry-run=client -o yamloc expose service app-ui \
  --dry-run=client -o yaml

oc expose pod POD_NAME # create a service for a specific pod.
oc expose deployment DEPLOYMENT_NAME # create a service for all pods managed by a controller, in this case a deployment controller.
oc expose service SERVICE_NAME # create a route that targets the specified service.

lab 2

lab start openshift-multipod

oc login -u developer -p developer https://api.ocp4.example.com:6443
oc project ocp-multipod

oc create deployment gitea --port 3030 \
  --image=registry.ocp4.example.com:8443/redhattraining/podman-gitea:latest
oc get po

oc create deployment gitea-postgres --port 5432 -o yaml \
  --image=registry.ocp4.example.com:8443/rhel9/postgresql-13:1 \
  --dry-run=client > postgres.yaml
vi postgres.yaml
##
   env:
        - name: POSTGRESQL_USER
          value: gitea
        - name: POSTGRESQL_PASSWORD
          value: gitea
        - name: POSTGRESQL_DATABASE
          value: gitea 
##

oc create -f postgres.yaml
oc get po
oc expose deployment gitea-postgres
oc get svc
oc expose deployment gitea
oc expose service gitea
oc get route

## Di browser web, buka URL dan gunakan konfigurasi berikut:gitea-ocp-multipod.apps.ocp4.example.com
## Jenis basis data: PostgreSQL
## Tuan rumah: gitea-postgres:5432
## Nama pengguna: gitea
## Kata sandi: gitea
## Nama basis data: gitea
## Domain Server: gitea-ocp-multipod.apps.ocp4.example.com
## URL Dasar Gitea: http://gitea-ocp-multipod.apps.ocp4.example.com
## Kemudian, klik Instal Gitea.

## Secara opsional, klik Daftar untuk membuat pengguna dan masuk.

lab finish openshift-multipod

lab soal

alt text

lab start openshift-lab
oc login -u developer -p developer https://api.ocp4.example.com:6443
oc project ocp-lab
cd ~/DO188/labs/openshift-lab/

oc create -f deployment.yaml
vi deployment.yaml
##
 matchLabels:
      app: quotes-api
  template:
    metadata:
      labels:
        app: quotes-api
##

vi service.yaml
##
apiVersion: v1
kind: Service
metadata:
  labels:
    app: quotes
  name: quotes-api
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: quotes-api
##
oc create -f service.yaml

oc describe service quotes-api
oc describe service quotes-ui
# Labels: app=quotes-ui

oc delete pod -l app=quotes-ui
oc get pod

lab finish openshift-lab

9

lab Komprehensif

alt text

lab start comprehensive-review

podman network create beeper-backend
podman network create beeper-frontend
podman volume create beeper-data

podman run -d --name beeper-db \
--net beeper-backend \
-v beeper-data:/var/lib/pgsql/data \
-e POSTGRESQL_USER=beeper \
-e POSTGRESQL_PASSWORD=beeper123 \
-e POSTGRESQL_DATABASE=beeper \
registry.ocp4.example.com:8443/rhel9/postgresql-13:1

cd ~/DO188/labs/comprehensive-review/beeper-backend

cat > Containerfile << EOF
FROM registry.ocp4.example.com:8443/ubi8/openjdk-17:1.12 as build_1

COPY --chown=jboss . .
RUN mvn -s settings.xml package
# output /home/jboss/target/beeper-1.0.0.jar

FROM registry.ocp4.example.com:8443/ubi8/openjdk-17-runtime:1.12
COPY --from=build_1 /home/jboss/target/beeper-1.0.0.jar .
ENTRYPOINT ["java", "-jar", "beeper-1.0.0.jar"]
EOF

podman build -t beeper-api:v1 .

podman run -d --name beeper-api \
-e DB_HOST=beeper-db \
--net beeper-backend \
--net beeper-frontend \
beeper-api:v1

cd ~/DO188/labs/comprehensive-review/beeper-ui

cat > Containerfile << EOF
FROM registry.ocp4.example.com:8443/ubi9/nodejs-18:1 as build_1
WORKDIR /opt/app-root/src
COPY . .
RUN npm install && npm run build
# output /opt/app-root/src/dist

FROM registry.ocp4.example.com:8443/ubi8/nginx-118:1

COPY nginx.conf /etc/nginx/
COPY --from=build_1 /opt/app-root/src/dist /usr/share/nginx/html

CMD nginx -g "daemon off;"
EOF

podman build -t beeper-ui:v1 .

podman run -d --name beeper-ui \
-p 8080:8080 \
--net beeper-frontend \
beeper-ui:v1

# open http://localhost:8080